package freelinz.smart.gwtex.user.client;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
/**
 * 此类为{@link DOM}类的扩展类，增加一些常用的操作功能
 * @author wpeace
 *
 */
public class DOMEx
{
    /**
     * 客户区的高度不包含浏览器的滚动条
     * 
     * @return 返回客户区的有效高度
     */
    public static native int getClientHeightNoScrollBar() /*-{
        if($doc.compatMode=='CSS1Compat') return $doc.documentElement.clientHeight;
        return $doc.body.clientHeight;
    }-*/;
    
    /**
     * 客户区的高度不包含浏览器的滚动条
     * 
     * @return 返回客户区的有效宽度
     */
    public static native int getClientWidthNoScrollBar()/*-{
        if($doc.compatMode=='CSS1Compat') return $doc.documentElement.clientWidth;
        return $doc.body.clientWidth;
     }-*/;
    /**
     * 取得当前的样式的属性值。首先取style的值，再取css的属性值或者浏览默认的属性值。此函数可以作为
     * {@link DOM#getStyleAttribute(Element, String)}}的代替函数
     * @param elem 元素
     * @param jsStyle css的javascript属性名
     * @return 属性值
     */
    public static native String getCurrentStyleAttribute(Element elem,String jsStyle)/*-{
        if(jsStyle=="float" || jsStyle == "styleFloat" || jsStyle =="cssFloat")
        {
            jsStyle = elem.currentStyle ? "styleFloat" : "cssFloat";
        }
        var ret = null;
        if(elem.style[jsStyle])
        {
            ret = elem.style[jsStyle];
        }else if(elem.currentStyle)
        {
            ret = elem.currentStyle[jsStyle];
        }else if(($doc.defaultView) && ($doc.defaultView.getComputedStyle))
        {
            //firefox中用格式如：border-top-width
            jsStyle = (jsStyle == "cssFloat")? "float" : 
                jsStyle.replace (/([A-Z])/g, "-$1").toLowerCase ();
            ret = $doc.defaultView.getComputedStyle(elem,
                "").getPropertyValue(jsStyle);
        }
        return (ret == null) ? null : ret; 
    }-*/;
    /**
     * 取得当前的样式的属性值，并转换为整数据。首先取style的值，再取css的属性值或者浏览默认的属性值，此函数可以作为
     * {@link DOM#getIntAttribute(Element, String)}的代替函数
     * @param elem 元素
     * @param jsStyle css的javascript属性名
     * @return 属性值
     * @see #getCurrentStyleAttribute(Element, String)
     */
    public static native int getIntCurrentStyleAttribute(Element elem,String jsStyle)/*-{
        if(jsStyle=="float" || jsStyle == "styleFloat" || jsStyle =="cssFloat")
        {
            jsStyle = elem.currentStyle ? "styleFloat" : "cssFloat";
        }
        var ret = null;
        if(elem.style[jsStyle])
        {
            ret = elem.style[jsStyle];
        }else if(elem.currentStyle)
        {
            ret = elem.currentStyle[jsStyle];
        }else if(($doc.defaultView) && ($doc.defaultView.getComputedStyle))
        {
            //firefox中用格式如：border-top-width、float格式
            jsStyle = (jsStyle == "cssFloat")? "float" : 
                jsStyle.replace (/([A-Z])/g, "-$1").toLowerCase ();
            ret = $doc.defaultView.getComputedStyle(elem,
                "").getPropertyValue(jsStyle);
        }
        var i = parseInt(ret);
        return (!i) ? 0 : i;
    }-*/;
    public static int getMarginTop(Element elem){
        return DOMEx.getIntCurrentStyleAttribute(elem, "marginTop");
    }
    public static int getMarginLeft(Element elem){
        return DOMEx.getIntCurrentStyleAttribute(elem, "marginLeft");
    }
    public static int getMarginRight(Element elem){
        return DOMEx.getIntCurrentStyleAttribute(elem, "marginRight");
    }
    public static int getMarginBottom(Element elem){
        return DOMEx.getIntCurrentStyleAttribute(elem, "marginBottom");
    }
    
    public static int getBorderTopWidth(Element elem)
    {
        return DOMEx.getIntCurrentStyleAttribute(elem, "borderTopWidth");
    }
    public static int getBorderLeftWidth(Element elem)
    {
        return DOMEx.getIntCurrentStyleAttribute(elem, "borderLeftWidth");
    }
    public static int getBorderRightWidth(Element elem)
    {
        return DOMEx.getIntCurrentStyleAttribute(elem, "borderRightWidth");
    }
    public static int getBorderBottomWidth(Element elem)
    {
        return DOMEx.getIntCurrentStyleAttribute(elem, "borderBottomWidth");
    }
    public static int getPaddingTop(Element elem)
    {
        return DOMEx.getIntCurrentStyleAttribute(elem, "paddingTop");
    }
    public static int getPaddingLeft(Element elem)
    {
        return DOMEx.getIntCurrentStyleAttribute(elem, "paddingLeft");
    }
    public static int getPaddingRight(Element elem)
    {
        return DOMEx.getIntCurrentStyleAttribute(elem, "paddingRight");
    }
    public static int getPaddingBottom(Element elem)
    {
        return DOMEx.getIntCurrentStyleAttribute(elem, "paddingBottom");
    }
    public static int getMarginTopBottom(Element elem)
    {
        return DOMEx.getMarginBottom(elem)+DOMEx.getMarginTop(elem);
    }
    public static int getMarginLeftRight(Element elem)
    {
        return DOMEx.getMarginLeft(elem)+DOMEx.getMarginRight(elem);
    }
    public static int getPaddingTopBottom(Element elem)
    {
        return DOMEx.getPaddingTop(elem)+DOMEx.getPaddingBottom(elem);
    }
    public static int getPaddingLeftRight(Element elem)
    {
        return DOMEx.getPaddingLeft(elem)+DOMEx.getPaddingRight(elem);
    }
    public static int getBorderTopBottom(Element elem)
    {
        return DOMEx.getBorderBottomWidth(elem)+DOMEx.getBorderTopWidth(elem);
    }
    public static int getBorderLeftRight(Element elem)
    {
        return DOMEx.getBorderLeftWidth(elem)+DOMEx.getBorderRightWidth(elem);
    }
    /**
     * 设置元素的高度与宽度
     * @param elem 元素
     * @param width 高度 包含margin、border、padding值
     * @param height 宽度 包含margin、border、padding值
     */
    public static void setOffsetMarginSize(Element elem,int width,int height){
        //在宽度中，已经包含了border、padding，所以不用再减去它们的值
        int w = width;
        int h = height;
        String tagName = DOM.getAttribute(elem, "tagName").toUpperCase();
        
        int borderWidth = DOMEx.getBorderLeftRight(elem);
        int paddingWidth = DOMEx.getPaddingLeftRight(elem);
        int marginWidth = DOMEx.getMarginLeftRight(elem);
        
        int borderHeight = DOMEx.getBorderTopBottom(elem);
        int paddingHeight = DOMEx.getPaddingTopBottom(elem);
        int marginHeight = DOMEx.getMarginTopBottom(elem);
        if(tagName.equals("INPUT"))
        {
            w -=(marginWidth + borderWidth +paddingWidth);
            h -=(marginHeight + borderHeight + paddingHeight);
        }else if(tagName.equals("BUTTON"))
        {
            w -=(marginWidth);
            h -=(marginHeight);
        }
        else if(tagName.equals("SELECT"))
        {
            w -=(marginWidth);
            if(DOM.getIntAttribute(elem, "size")>0)
            {
                h -=(marginHeight + borderHeight-2);
            }
            else
            {
                h = -1;
            }
        }
        else 
        {
            w -=(marginWidth + borderWidth +paddingWidth);
            h -=(marginHeight + borderHeight + paddingHeight);
        }
        w = w < 0 ? 0:w;
        h = h < 0 ? 0:h;
        DOM.setStyleAttribute(elem, "height", h+"px");
        DOM.setStyleAttribute(elem, "width", w+"px");
    }
    public static native void setStyleAttributeEx(Element elem,String jsStyle,String value)/*-{
        if(jsStyle=="float" || jsStyle == "styleFloat" || jsStyle =="cssFloat")
        {
            jsStyle = elem.style.styleFloat || elem.style.styleFloat==""  ? "styleFloat":"cssFloat";
        }
        elem.style[jsStyle]=value;
    }-*/;
}
